import 'braft-editor/dist/index.css'
import 'braft-editor/dist/output.css'
import 'braft-extensions/dist/table.css'
import 'braft-extensions/dist/code-highlighter.css'
import 'braft-extensions/dist/table.css'
import 'prismjs/themes/prism-okaidia.css'

import React from 'react'
import BraftEditor from 'braft-editor'
import styles from './style.less'

import { useEffect, useState, useRef } from 'react';
import { Button, Modal } from 'antd';
import { RightOutlined, LeftOutlined, DownOutlined } from '@ant-design/icons'
import { useMemo } from 'react';
import classNames from 'classnames';
import CodeHighlighter from 'braft-extensions/dist/code-highlighter'
import { ContentUtils } from 'braft-utils'
import StringUtils from '@/utils/StringUtils'
import CopyedImageModal from './CopyedImageModal'
import 'prismjs/components/prism-java'
import 'prismjs/components/prism-sql'
import 'prismjs/components/prism-json'

const totalControls = [
    'undo', 'redo', 'separator',
    'font-size', 'line-height', 'letter-spacing', 'separator',
    'text-color', 'bold', 'italic', 'underline', 'strike-through', 'separator',
    'superscript', 'subscript', 'remove-styles', 'emoji', 'separator', 'text-indent', 'text-align', 'separator',
    'headings', 'list-ul', 'list-ol', 'blockquote', 'code', 'separator',
    'link', 'separator', 'hr', 'separator',
    // 'media',
    'separator',
    'clear', "fullscreen"
];

const fontColors = [
    '#000000', '#333333', '#666666', '#999999', '#cccccc', '#ffffff',
    '#61a951', '#16a085', '#07a9fe', '#003ba5', '#8e44ad', '#f32784',
    '#ff0000', '#d35400', '#f39c12', '#fdda00', '#7f8c8d', '#2c3e50'
]

const simpleControls = [
    'undo', 'redo', 'separator',
    'text-color', 'bold', 'italic', 'separator',
    'emoji', 'separator',
    'headings', 'list-ul', 'list-ol', 'blockquote', 'code', 'separator',
    'link', 'separator',
    'separator',
    'clear', "fullscreen"
];

const verySimpleControls = [
    'text-color', 'bold', 'italic', 'separator', 'emoji', 'headings', 'link', 'code', 'clear', "fullscreen"
]

BraftEditor.use(CodeHighlighter({
    syntaxs: [
        {
            name: 'JavaScript',
            syntax: 'javascript'
        }, {
            name: 'HTML',
            syntax: 'html'
        }, {
            name: 'CSS',
            syntax: 'css'
        }, {
            name: 'Java',
            syntax: 'java',
        }, {
            name: 'SQL',
            syntax: 'sql'
        }, {
            name: 'JSON',
            syntax: 'json'
        }
    ],
}))

const RichTextEdit = (props) => {

    const {
        value,
        onChange,
        onSave,
        onCancel,
        className,
        size = "middle",
        showMoreControl = true,
        showFormButton = true,
    } = props;

    const [controls, setControls] = useState(verySimpleControls)
    const [isShowAllControls, setIsShowAllControls] = useState(false)
    const [editorState, setEditorState] = useState();
    const [currentCopyFile, setCurrentCopyFile] = useState(null);
    useEffect(() => {
        if (typeof value === "string") {
            setEditorState(BraftEditor.createEditorState(value))
        } else {
            setEditorState(BraftEditor.createEditorState(value?.raw || value?.text))
        }
        if (!showMoreControl) {
            setIsShowAllControls(true)
        }
    }, [])

    useEffect(() => {
        setControls(size === 'small' ? verySimpleControls : simpleControls)
    }, [size])


    const moreControls = [
        'separator',
        {
            key: 'more', // 控件唯一标识，必传
            type: 'button',
            title: isShowAllControls ? "收起" : "更多", // 指定鼠标悬停提示文案
            className: 'more-button', // 指定按钮的样式名
            html: null, // 指定在按钮中渲染的html字符串
            text: (isShowAllControls ? <LeftOutlined /> : <RightOutlined />), // 指定按钮文字，此处可传入jsx，若已指定html，则text不会显示
            onClick: () => {
                console.log(isShowAllControls)
                if (isShowAllControls) {
                    setIsShowAllControls(false)
                } else {
                    setIsShowAllControls(true)
                }
            },
        }
    ]

    const actionControls = [{
        key: 'save', // 控件唯一标识，必传
        type: 'button',
        text: (<div className={styles.saveButton}>保存</div>), // 指定按钮文字，此处可传入jsx，若已指定html，则text不会显示
        onClick: () => {
            if (onSave) {
                onSave({
                    text: editorState.toHTML(),
                    raw: editorState.toRAW()
                })
            }
        },
    }, {
        key: 'cancel', // 控件唯一标识，必传
        type: 'button',
        text: (<div className={styles.cancelButton}>取消</div>), // 指定按钮文字，此处可传入jsx，若已指定html，则text不会显示
        onClick: () => {
            if (onCancel) {
                onCancel()
            }
        },
    }]


    useMemo(() => {
        if (isShowAllControls) {
            setControls(totalControls)
        } else {
            setControls(size === 'small' ? verySimpleControls : simpleControls)
        }
    }, [isShowAllControls])



    const handleChange = (editorState) => {
        // console.log(editorState.toRAW(true))
        // console.log(editorState.toRAW())
        setEditorState(editorState)
        if (onChange) {
            onChange({
                text: editorState.toHTML(),
                raw: editorState.toRAW()
            })
        }
    }
    const unionClassName = classNames(styles.editorWrapper, 'editor-wrapper', {
        [styles.largeEditor]: size === 'large',
        [styles.middleEditor]: size === 'middle',
        [styles.smallEditor]: size === 'small',
    }, className);

    // https://draftjs.org/docs/api-reference-editor
    // https://github.com/margox/braft-editor/blob/master/src/editor/index.jsx
    const handlePastedText = (text, html, draftEditorState) => {
        // console.log(html.length,StringUtils.removeSpanTag(html,"span").length,text.length)
        const noSpanText = StringUtils.removeSpanTag(html)
        // console.log(html, '----', noSpanText, '----',text)
        // console.log("span ----", noSpanText, html.length, noSpanText.length / html.length);
        if (html && noSpanText &&  noSpanText.length / html.length < 0.4) {
            console.log("only insert text")
            // 用户描述文字的 span 标签太多了，如果是span太多的情况，舍弃标签，直接插入文本
            setEditorState(ContentUtils.insertText(editorState, text))
            return "handled"
        }
    }

    const onInsertImage = (imageUrl) => {
        setCurrentCopyFile(null)
        console.log(imageUrl)
        setEditorState(ContentUtils.insertMedias(editorState, [{
            type: 'IMAGE',
            url: imageUrl
        }]))
    }

    const handlePastedFiles = (files, selection) => {
        if (files && files.length === 1) {
            if (files[0].type.indexOf("image") > -1) {
                setCurrentCopyFile(files[0])
            }
        }
        return true;
    }
    const renderExtendControls = () => {
        if (showMoreControl) {
            return showFormButton ? [...moreControls, ...actionControls] : moreControls
        } else {
            return showFormButton ? [...actionControls] : []
        }
    }
    return (
        <>
            <div className={unionClassName}>
                <BraftEditor
                    id="braft-editor"
                    colors={fontColors}
                    textBackgroundColor={fontColors}
                    extendControls={renderExtendControls()}
                    controls={controls}
                    onSave={(editorState) => {
                        if (onSave) {
                            onSave({
                                text: editorState.toHTML(),
                                raw: editorState.toRAW()
                            })
                        }
                    }}
                    handlePastedText={handlePastedText}
                    handlePastedFiles={handlePastedFiles}
                    value={editorState}
                    onChange={handleChange}
                />
            </div>
            <CopyedImageModal
                onInsertImage={onInsertImage}
                onCancel={() => {
                    setCurrentCopyFile(null)
                }}
                file={currentCopyFile}></CopyedImageModal>
        </>

    )
}


const RichText = (props) => {

    const {
        value,
        border,
        collectable,
        collectHeight = 60,
        collectChange,
        collectStyle = "top"
    } = props;

    const contentRef = useRef()

    const [collectFlag, setCollectFlag] = useState(true)
    const [needCollect, setNeedCollect] = useState(false)
    const [style, setStyle] = useState({})

    useEffect(() => {
        Prism.hooks.add('before-highlight', function (env) {
            env.element.innerHTML = env.element.innerHTML.replace(/<br\s*\/?>/g, '\n');
            env.code = env.element.textContent.replace(/^(?:\r?\n|\r)/, '');
        });
        Prism.highlightAll();
    }, [])

    useEffect(() => {
        if (collectable && collectFlag) {
            const selfHeight = contentRef.current && contentRef.current.clientHeight;
            let needCollect = selfHeight > collectHeight;
            setNeedCollect(needCollect)
            if (needCollect) {
                setStyle({
                    height: collectHeight + "px",
                    overflow: "hidden",
                    textOverflow: "ellipsis",
                    position: "relative"
                })
            }
        } else {
            setStyle({})
        }
        if (collectChange) {
            collectChange(collectFlag)
        }
    }, [collectFlag])

    const className = classNames(styles.outputContent, "braft-output-content", {
        [styles.outputContentBorder]: border,
        [styles.noBorder]: !border,
    });

    const topCollectButton = () => {
        const selfHeight = contentRef.current && contentRef.current.clientHeight;
        if (needCollect) {
            return <div style={{
                fontSize: "16px",
                position: "absolute",
                right: "16px"
            }}>
                <Button type="link" shape="circle" onClick={() => { setCollectFlag(!collectFlag) }} icon={<DownOutlined rotate={collectFlag ? 0 : 180} />}>{collectFlag ? "展开" : "收起"}</Button>
            </div>
        }
    };


    const buttomCollectButton = () => {
        const selfHeight = contentRef.current && contentRef.current.clientHeight;
        if (needCollect) {
            return <div>
                <Button type="link" onClick={() => { setCollectFlag(!collectFlag) }} icon={<DownOutlined rotate={collectFlag ? 0 : 180} />}>
                    {collectFlag ? "展开" : "收起"}
                </Button>
            </div>
        }
    };

    return (
        <div>
            <div style={style}>
                {collectable && (collectStyle === "top" && topCollectButton())}
                <div className={className}>
                    <div ref={contentRef} className={styles.code} dangerouslySetInnerHTML={{ __html: value }}>
                    </div>
                </div>
                {needCollect && collectFlag && <div style={{
                    width: "100%",
                    height: "10px",
                    backgroundColor: "white",
                    position: "absolute",
                    background: "linear-gradient(to bottom,rgba(0,0,0,0),white)",
                    top: collectHeight - 10
                }} >
                </div>}
            </div>
            {collectable && (collectStyle === "buttom" && buttomCollectButton())}
        </div>
    )

}

export { RichTextEdit };
export default RichText;

